﻿using System;
using System.Globalization;

namespace Microsoft.Xna.Framework.Graphics
{
	/// <summary>
	/// Contains depth-stencil state for the device.
	/// </summary>
	public class DepthStencilState : GraphicsResource
	{
		#region Fields
		/// <summary>
		/// A built-in state object with default settings for using a depth stencil buffer.
		/// </summary>
		public static readonly DepthStencilState Default = new DepthStencilState(true, true, "DepthStencilState.Default");

		private bool depthBufferEnable;
		private bool depthBufferWriteEnable;
		internal bool isBound;

		/// <summary>
		/// A built-in state object with settings for enabling a read-only depth stencil buffer.
		/// </summary>
		public static readonly DepthStencilState DepthRead = new DepthStencilState(true, false, "DepthStencilState.DepthRead");

		/// <summary>
		/// A built-in state object with settings for not using a depth stencil buffer.
		/// </summary>
		public static readonly DepthStencilState None = new DepthStencilState(false, false, "DepthStencilState.None");
		#endregion

		#region Properties
		/// <summary>
		/// Enables or disables depth buffering. The default is true.
		/// </summary>
		public bool DepthBufferEnable
		{
			get { return depthBufferEnable; }
			set
			{
				ThrowIfBound();
				depthBufferEnable = value;
			}
		}

		/// <summary>
		/// Enables or disables writing to the depth buffer. The default is true.
		/// </summary>
		public bool DepthBufferWriteEnable
		{
			get { return depthBufferWriteEnable; }
			set
			{
				ThrowIfBound();
				depthBufferWriteEnable = value;
			}
		}
		#endregion

		#region Constructors
		/// <summary>
		/// Creates an instance of DepthStencilState with default values.
		/// </summary>
		public DepthStencilState()
		{
			depthBufferEnable = true;
			depthBufferWriteEnable = true;
			isBound = false;
		}

		private DepthStencilState(bool depthEnable, bool depthWriteEnable, string name)
		{
			depthBufferEnable = depthEnable;
			depthBufferWriteEnable = depthWriteEnable;
			isBound = true;
			base.Name = name;
		}
		#endregion

		private void ThrowIfBound()
		{
			if (this.isBound)
			{
				throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, FrameworkResources.BoundStateObject, typeof(DepthStencilState).Name));
			}
		}
	}
}
